/*
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *    ------------------------------------------------------------------------
 *    Copyright (C) 2011-
 *    Salvatore Ruggieri
 *    Dipartimento di Informatica, Universita' di Pisa
 *    Pisa, Italy
 *    ------------------------------------------------------------------------
 *
 */
package LDA;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.*;

/**
 * Static methods for getting readers and writers from filenames or URLs,
 * reading tokens from readers.
 */
public abstract class IOUtil {

	/** Newline character */
	public static final String newline = System.getProperty("line.separator");

	/**
	 * Get a Reader given a resource name. Resource names can be filenames or
	 * urls possibly gzipped (if ending with the ".gz" extension).
	 * 
	 * @param name
	 *            resource name
	 * @return reader
	 */
	public static BufferedReader getReader(String name) throws IOException {
		InputStream is;

		if (name.equals(""))
			is = System.in;
		else {
			try {
				is = new FileInputStream(name);
			} catch (FileNotFoundException e) {
				try {
					URL url = new URL(name);
					is = url.openStream();
				} catch (MalformedURLException m) {
					throw (new IOException(name + ": not a file or an URL."));
				}
			}
			if (name.endsWith(".gz"))
				is = new GZIPInputStream(is);
		}

		return new BufferedReader(new InputStreamReader(is));
	}

	/**
	 * Return the content of a resource as a String.
	 * 
	 * @param name
	 *            resource name
	 * @return the content of the resource, accessed with getReader()
	 */
	public static String getFileContent(String name) throws IOException {
		BufferedReader r = getReader(name);
		StringBuffer s = new StringBuffer(4096);
		String line;
		while ((line = r.readLine()) != null) {
			s.append(line);
			s.append(IOUtil.newline);
		}
		r.close();
		return s.toString();
	}

	/**
	 * Get a PrintWriter given a resource name, possibly in append mode.
	 * Resource names can be filenames possibly gzipped (if ending with the
	 * ".gz" extension).
	 * 
	 * @param name
	 *            resource name
	 * @param append
	 *            true if the resource is opened in append mode
	 */
	public static PrintWriter getWriter(String name, boolean append)
			throws IOException {
		OutputStream os;

		if (name.equals("")) {
			os = System.out;
		} else {
			os = new FileOutputStream(name, append);

			if (name.endsWith(".gz"))
				os = new GZIPOutputStream(os);
		}

		return new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)),
				true);
	}

	/**
	 * Get a PrintWriter given a resource name. Resource names can be filenames
	 * possibly gzipped (if ending with the ".gz" extension).
	 * 
	 * @param name
	 *            resource name
	 */
	public static PrintWriter getWriter(String name) throws IOException {
		return getWriter(name, false);
	}

	/**
	 * Return the array of comma-separated tokens in a line read from a
	 * BufferedReader.
	 * 
	 * @param in
	 *            input reader
	 * @return the array of tokens or null if no line was read.
	 */
	public static String[] readTokens(BufferedReader in) throws IOException {
		return readTokens(in, ",");
	}

	/**
	 * Return the array of tokens in a line read from a BufferedReader.
	 * 
	 * @param in
	 *            input reader
	 * @param sep
	 *            token separator
	 * @return the array of tokens or null if no line was read.
	 */
	public static String[] readTokens(BufferedReader in, String sep)
			throws IOException {
		String line = in.readLine();
		if (line == null)
			return null;

		StringTokenizer st = new StringTokenizer(line, sep);
		String[] result = new String[st.countTokens()];
		int pos = 0;

		while (st.hasMoreTokens())
			result[pos++] = st.nextToken();

		return result;

	}

	/**
	 * Copy a resource line by line.
	 * 
	 * @param in
	 *            input resource name
	 * @param out
	 *            output resource name.
	 */
	public static void copy(String in, String out) throws IOException {
		BufferedReader r = getReader(in);
		PrintWriter w = getWriter(out);
		String line;
		while ((line = r.readLine()) != null)
			w.println(line);
		r.close();
		w.close();
	}

	/**
	 * Read a file of properties.
	 * 
	 * @param propsFileName
	 *            the filename containing properties
	 * @return a Property object
	 */
	public static Properties readProps(String propsFileName) throws IOException {
		Properties props = new Properties();
		FileInputStream in = new FileInputStream(propsFileName);
		props.load(in);
		in.close();
		return props;
	}

}
